home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1996 March
/
EnigmA AMIGA RUN 05 (1996)(G.R. Edizioni)(IT)[!][issue 1996-03][Skylink CD IV].iso
/
earcd
/
dtype
/
txtdtpch.lha
/
textdtpatch
/
textdtpatch.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-07-04
|
13KB
|
555 lines
/*
** $PROJECT: text.datatype patch
**
** $VER: textdtpatch.c 39.1 (04.07.95)
**
** by
**
** Stefan Ruppert , Windthorststraße 5 , 65439 Flörsheim , GERMANY
**
** (C) Copyright 1995
** All Rights Reserved !
**
** $HISTORY:
**
** 04.07.95 : 039.001 : initial
*/
/* ----------------------------- version data ----------------------------- */
/*FS*/ /* $STARTDEFINE: "BumpRev defines"*/
#define VERSION 39
#define REVISION 1
#define DATE "3.7.95"
#define VERS "textdtpatch 39.1"
#define VSTRING "textdtpatch 39.1 (3.7.95)\r\n"
#define VERSTAG "\0$VER: textdtpatch 39.1 (3.7.95)"
/*FE*/ /* $ENDDEFINE: */
/* ------------------------------- autodoc -------------------------------- */
/*FS*/ /*"AutoDoc"*/
/*GB*** textdtpatch **********************************************************
*
* NAME
* textdtpatch - patches the text.datatype to support search method
*
* TEMPLATE
* none
*
* REQUIREMENT
* reqtools.library V38, OS3.0 or higher
*
* FUNCTION
* This program patches the text.datatype, so that the new one can
* search for a string. The following key commands are supported :
*
* Return (STM_ACTIVATE_FIELD) - opens a reqtools requester to enter
* the search string and searches for that if confirmed.
*
* Tab (STM_NEXT_FIELD) , '>' (STM_BROWSE_NEXT) searches for the next
* occurrence of the string.
*
* Shift-Tab (STM_PREV_FIELD) , '<' (STM_BROWSE_PREV) searches for the
* previous occurrence of the string.
*
* INSTALLATION
* 1. Copy textdtpatch to your c: or anywhere you like.
* 2. Add in your S:User-Startup following line:
* run >nil: c:textdtpatch
* 3. To terminate textdtpatch send a break (Ctrl-C).
*
* SEE ALSO
* text.datatype
*
* AUTHOR
* Stefan Ruppert
* Windthorststrasse 5
* 65439 Floersheim Main
* GERMANY
* EMail: ruppert@vs3.informatik.fh-wiesbaden.de
*
*****************************************************************************/
/*FE*/
/* ------------------------------- include -------------------------------- */
#include <exec/types.h>
#include <exec/memory.h>
#include <clib/alib_protos.h>
#include <clib/datatypes_protos.h>
#include <clib/dos_protos.h>
#include <clib/dtclass_protos.h>
#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <pragmas/datatypes_pragmas.h>
#include <pragmas/dos_pragmas.h>
#include <pragmas/dtclass_pragmas.h>
#include <pragmas/exec_sysbase_pragmas.h>
#include <pragmas/intuition_pragmas.h>
#include <dos/dostags.h>
#include <datatypes/textclass.h>
#include <clib/reqtools_protos.h>
#include <pragmas/reqtools.h>
#include <libraries/reqtools.h>
#include <string.h>
/* ------------------------- register defintions -------------------------- */
#define RegCall __asm
#define GetA4 __saveds
#define REGA0 register __a0
#define REGA1 register __a1
#define REGA2 register __a2
/* -------------------------- debug definitions --------------------------- */
#ifdef DEBUG
#define bug kprintf
extern void bug(char *fmt,...);
#define D(x) x
#define DB(x) { bug(__FILE__ "(%4ld):" __FUNC__ "() :",__LINE__); \
bug x; \
}
#else
#define bug
#define D(x)
#define DB(x)
#endif
/* -------------------------- static data items --------------------------- */
static const STRPTR version = VERSTAG;
static const STRPTR prgname = "textdtpatch";
/* ------------------------------ prototypes ------------------------------ */
RegCall GetA4 ULONG mytextdtdispatcher(REGA0 Class *cl,REGA2 Object *obj,REGA1 Msg msg);
ULONG DoAsyncMethod(Class *cl,Object *obj,Msg msg,ULONG tag1,...);
ULONG DoAsyncMethodA(Class *cl,Object *obj,Msg msg,struct TagItem *tagList);
ULONG NotifyAttrs(Object * obj, void * ginfo, ULONG flags, ULONG tag1,...);
ULONG getstring(Class *cl,Object *obj,struct dttGetString *msg);
LONG strseg(struct Line *line,STRPTR str,LONG slen);
ULONG searchstring(Class *cl,Object *obj,LONG direction,struct dttSearchText *msg);
/* ------------------------- template definition -------------------------- */
#define TRG(msg) ((struct dtTrigger *) (msg))
#define SM(msg) ((struct dttGetString *) (msg))
#define DTTM_GETSTRING 0x20000
#define DTTM_SEARCHNEXT 0x20001
#define DTTM_SEARCHPREV 0x20002
struct ClassData
{
struct Library *cd_SysBase;
struct Library *cd_DOSBase;
struct Library *cd_IntuitionBase;
#if 0
struct Library *cd_DataTypesBase;
#endif
};
struct dttGetString
{
ULONG MethodID;
struct GadgetInfo dttgs_GInfo;
LONG dttgs_SearchMethod;
};
struct dttSearchText
{
ULONG MethodID;
struct GadgetInfo *dttst_GInfo;
STRPTR dttst_Text;
LONG dttst_TextLen;
};
struct MyTextDTData
{
UBYTE Buffer[100];
LONG FoundLine;
struct dttGetString Msg;
};
#define IntuitionBase cd->cd_IntuitionBase
#define DOSBase cd->cd_DOSBase
#define DataTypesBase cd->cd_DataTypesBase
/* --------------------------- main entry point --------------------------- */
GetA4 int main(void)
{
struct Library *SysBase = *((struct Library **) 4L);
struct ClassData *cd;
if(SysBase->lib_Version < 39)
return(RETURN_FAIL);
if((cd = AllocVec(sizeof(struct ClassData), MEMF_CLEAR | MEMF_ANY)))
{
struct Library *DTClassBase;
cd->cd_SysBase = SysBase;
DOSBase = OpenLibrary("dos.library",39);
IntuitionBase = OpenLibrary("intuition.library",39);
if((DTClassBase = OpenLibrary("datatypes/text.datatype",39)))
{
struct IClass *TextDTClass;
if((TextDTClass = ObtainEngine()))
{
struct IClass *MyTextDTClass;
ClassID oldclassid;
oldclassid = TextDTClass->cl_ID;
TextDTClass->cl_ID = "org_text.datatype";
if((MyTextDTClass = MakeClass("text.datatype",NULL,TextDTClass,sizeof(struct MyTextDTData),0)))
{
MyTextDTClass->cl_Dispatcher.h_Entry = (HOOKFUNC) mytextdtdispatcher;
MyTextDTClass->cl_UserData = (ULONG) cd;
AddClass(MyTextDTClass);
Wait(SIGBREAKF_CTRL_C);
RemoveClass(MyTextDTClass);
while(!FreeClass(MyTextDTClass))
Delay(50);
} else
Printf("can't make new text.datatype class !\n");
TextDTClass->cl_ID = oldclassid;
} else
Printf("can't obtain old text.datatype class !\n");
CloseLibrary(DTClassBase);
} else
Printf("can't open text.datatype !\n");
CloseLibrary(IntuitionBase);
CloseLibrary(DOSBase);
FreeVec(cd);
}
return(RETURN_OK);
}
/*FS*/ ULONG DoAsyncMethod(Class *cl,Object *obj,Msg msg,ULONG tag1,...)
{
return(DoAsyncMethodA(cl,obj,msg,(struct TagItem *) &tag1));
}
/*FE*/
/*FS*/ /*"ULONG DoAsyncMethodA(Class *cl,Object *obj,Msg msg,struct TagItem *tagList)"*/
struct AsyncMethodMsg
{
struct Message amm_ExecMessage;
Object *amm_Object;
Msg amm_Msg;
};
RegCall GetA4 ULONG asyncmethodfunc(void)
{
struct Library *SysBase = *((struct Library **) 4L);
struct Process *proc = (struct Process *) FindTask(NULL);
Object *obj;
Msg msg;
struct AsyncMethodMsg *amsg;
WaitPort(&proc->pr_MsgPort);
amsg = (struct AsyncMethodMsg *) GetMsg(&proc->pr_MsgPort);
obj = amsg->amm_Object;
msg = amsg->amm_Msg;
ReplyMsg(&amsg->amm_ExecMessage);
D(bug("recieved object : %lx, msg : %lx\n",obj,msg));
return(DoMethodA(obj,msg));
}
#define SysBase cd->cd_SysBase
ULONG DoAsyncMethodA(Class *cl,Object *obj,Msg msg,struct TagItem *tagList)
{
struct ClassData *cd = (struct ClassData *) cl->cl_UserData;
struct AsyncMethodMsg amsg;
struct Process *proc = NULL;
struct MsgPort *mport;
DB(("before CreateMsgPort() !\n"));
if((mport = CreateMsgPort()))
{
DB(("after CreateMsgPort() !\n"));
amsg.amm_Object = obj;
amsg.amm_Msg = msg;
amsg.amm_ExecMessage.mn_Node.ln_Type = NT_MESSAGE;
amsg.amm_ExecMessage.mn_ReplyPort = mport;
DB(("before CreateNewProcTags() !\n"));
if((proc = CreateNewProcTags(NP_Entry,asyncmethodfunc,
(tagList) ? TAG_MORE : TAG_IGNORE,tagList,
TAG_DONE)))
{
DB(("sending object : %lx, msg : %lx\n",obj,msg));
PutMsg(&proc->pr_MsgPort,&amsg.amm_ExecMessage);
WaitPort(mport);
}
DeleteMsgPort(mport);
}
return((ULONG) proc);
}
/*FE*/
/*FS*/ ULONG NotifyAttrs(Object * obj, void * ginfo, ULONG flags, ULONG tag1,...)
{
return(DoMethod(obj, OM_NOTIFY, &tag1, ginfo, flags));
}
/*FE*/
/*FS*/ ULONG getstring(Class *cl,Object *obj,struct dttGetString *msg)
{
struct MyTextDTData *data = INST_DATA(cl,obj);
struct ClassData *cd = (struct ClassData *) cl->cl_UserData;
struct GadgetInfo *ginfo = &msg->dttgs_GInfo;
struct Library *ReqToolsBase;
ULONG retval = 0;
DB(("before getstring() !\n"));
if((ReqToolsBase = OpenLibrary("reqtools.library",38)))
{
retval = rtGetString(data->Buffer,sizeof(data->Buffer),
"Text Datatype Search String",NULL,
RT_Window ,ginfo->gi_Window,
RT_ReqPos ,REQPOS_CENTERWIN,
RT_LockWindow ,TRUE,
TAG_DONE);
CloseLibrary(ReqToolsBase);
if(retval)
{
Forbid();
DoMethod(obj,msg->dttgs_SearchMethod,ginfo,data->Buffer,strlen(data->Buffer));
Permit();
}
}
return(retval);
}
/*FE*/
/*FS*/ LONG strseg(struct Line *line,STRPTR str,LONG slen)
{
STRPTR text = line->ln_Text;
STRPTR ptr;
LONG llen = line->ln_TextLen;
LONG len;
D({UBYTE dbbuf[256];
strncpy(dbbuf,line->ln_Text,line->ln_TextLen);
dbbuf[line->ln_TextLen] ='\0';
bug("%s\n",dbbuf);
});
while(llen >= slen)
{
ptr = str;
len = slen;
while(*text == *ptr)
{
text++;
ptr++;
llen--;
len--;
}
if(len==0)
return(1);
else
{
text++;
llen--;
}
}
return(0);
}
/*FE*/
/*FS*/ ULONG searchstring(Class *cl,Object *obj,LONG direction,struct dttSearchText *msg)
{
struct ClassData *cd = (struct ClassData *) cl->cl_UserData;
struct MyTextDTData *data = INST_DATA(cl,obj);
struct List *list;
DB(("search for : \"%s\" !\n",msg->dttst_Text));
if(GetAttr(TDTA_LineList,obj,(ULONG *) &list))
{
struct Line *line;
LONG len = msg->dttst_TextLen;
LONG found = data->FoundLine;
LONG y = 0;
line = (struct Line *) list->lh_Head;
if(direction == -1)
found--;
while(y <= found && line->ln_Link.mln_Succ)
{
if(line->ln_Flags & LNF_LF)
y++;
line = (struct Line *) line->ln_Link.mln_Succ;
}
found = -1;
if(direction == -1)
{
if(line->ln_Link.mln_Pred)
line = (struct Line *) line->ln_Link.mln_Pred;
while(line->ln_Link.mln_Pred && found == -1)
{
if(line->ln_Flags & LNF_LF)
y--;
if(line->ln_TextLen >= len)
{
if(strseg(line,msg->dttst_Text,msg->dttst_TextLen))
{
found = y;
break;
}
}
line = (struct Line *) line->ln_Link.mln_Pred;
}
} else
{
while(line->ln_Link.mln_Succ && found == -1)
{
if(line->ln_TextLen >= len)
{
if(strseg(line,msg->dttst_Text,msg->dttst_TextLen))
{
found = y;
break;
}
}
if(line->ln_Flags & LNF_LF)
y++;
line = (struct Line *) line->ln_Link.mln_Succ;
}
}
data->FoundLine = found;
if(found < 0)
{
DisplayBeep(msg->dttst_GInfo->gi_Screen);
found = 0;
}
NotifyAttrs(obj,msg->dttst_GInfo,0,DTA_TopVert,found,TAG_DONE);
}
return(0);
}
/*FE*/
/*FS*/ RegCall GetA4 ULONG mytextdtdispatcher(REGA0 Class *cl,REGA2 Object *obj,REGA1 Msg msg)
{
struct MyTextDTData *data = INST_DATA(cl,obj);
ULONG retval = 0;
switch(msg->MethodID)
{
case OM_NEW:
{
Object *newobj;
if((newobj = (Object *) DoSuperMethodA(cl,obj,msg)))
{
data = INST_DATA(cl,newobj);
data->FoundLine = -1;
DB(("new text.datatype object : %lx\n",newobj));
retval = (ULONG) newobj;
}
}
break;
case DTM_TRIGGER:
{
ULONG searchmethod = DTTM_SEARCHNEXT;
switch(TRG(msg)->dtt_Function)
{
case STM_PREV_FIELD:
case STM_BROWSE_PREV:
searchmethod = DTTM_SEARCHPREV;
case STM_NEXT_FIELD:
case STM_BROWSE_NEXT:
if(data->Buffer[0])
{
DoMethod(obj,searchmethod,TRG(msg)->dtt_GInfo,data->Buffer,strlen(data->Buffer));
break;
}
case STM_ACTIVATE_FIELD:
data->Msg.MethodID = DTTM_GETSTRING;
/* copy the full GadgetInfo, because this request is asyncron and datatypes
* creates this structure on the stack (Oh No) !
*/
data->Msg.dttgs_GInfo = *TRG(msg)->dtt_GInfo;
data->Msg.dttgs_SearchMethod = searchmethod;
DB(("before async method !\n"));
DoAsyncMethod(cl,obj,(Msg) &data->Msg,NP_Name,"text.datatype getstring process",TAG_DONE);
break;
}
}
break;
case DTTM_GETSTRING:
retval = getstring(cl,obj,(struct dttGetString *) msg);
break;
case DTTM_SEARCHNEXT:
retval = searchstring(cl,obj,1,(struct dttSearchText *) msg);
break;
case DTTM_SEARCHPREV:
retval = searchstring(cl,obj,-1,(struct dttSearchText *) msg);
break;
default:
retval = DoSuperMethodA(cl,obj,msg);
}
return(retval);
}
/*FE*/